{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "96709ec6-434d-4190-9adc-71200e2876df",
   "metadata": {},
   "source": [
    "Chapter 06\n",
    "\n",
    "# 计算坐标\n",
    "《线性代数》 | 鸢尾花书：数学不难"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "fdedf8e9-22a4-4e53-99e2-2ddcee3dc8d9",
   "metadata": {},
   "source": [
    "这段代码的核心思想是**将向量 $\\boldsymbol{a}$ 从标准基坐标系转换到一个新的基底 $A$ 所定义的坐标系中**，即在给定基底 $A$ 下求向量 $\\boldsymbol{a}$ 的坐标表示（即其坐标向量）。\n",
    "\n",
    "---\n",
    "\n",
    "### 1. 向量的标准坐标表示\n",
    "\n",
    "首先，我们定义了一个二维列向量：\n",
    "\n",
    "$$\n",
    "\\boldsymbol{a} = \\begin{bmatrix} 3 \\\\ 4 \\end{bmatrix}\n",
    "$$\n",
    "\n",
    "这个向量是用标准正交基 $\\{ \\boldsymbol{e}_1, \\boldsymbol{e}_2 \\}$ 表示的，其中 $\\boldsymbol{e}_1 = \\begin{bmatrix}1 \\\\ 0\\end{bmatrix}$，$\\boldsymbol{e}_2 = \\begin{bmatrix}0 \\\\ 1\\end{bmatrix}$。换句话说，$\\boldsymbol{a}$ 是在标准坐标系下的表示形式。\n",
    "\n",
    "---\n",
    "\n",
    "### 2. 变换到新基底下的目标\n",
    "\n",
    "我们希望表示同一个几何向量 $\\boldsymbol{a}$，但在一个新的基底 $A = [\\boldsymbol{v}_1 \\ \\boldsymbol{v}_2]$（即列向量 $\\boldsymbol{v}_1$ 和 $\\boldsymbol{v}_2$ 组成的矩阵）下。换句话说，我们想找到新的坐标向量 $\\boldsymbol{a}'$，使得：\n",
    "\n",
    "$$\n",
    "\\boldsymbol{a} = A \\cdot \\boldsymbol{a}'\n",
    "$$\n",
    "\n",
    "这里，$\\boldsymbol{a}'$ 是 $\\boldsymbol{a}$ 在基底 $A$ 下的坐标向量。\n",
    "\n",
    "---\n",
    "\n",
    "### 3. 求解方法\n",
    "\n",
    "我们将上述等式两边左乘 $A^{-1}$（即基底变换矩阵的逆）来解出 $\\boldsymbol{a}'$：\n",
    "\n",
    "$$\n",
    "A^{-1} \\boldsymbol{a} = A^{-1} A \\cdot \\boldsymbol{a}' = \\boldsymbol{a}'\n",
    "$$\n",
    "\n",
    "因此，新的坐标向量为：\n",
    "\n",
    "$$\n",
    "\\boldsymbol{a}' = A^{-1} \\boldsymbol{a}\n",
    "$$\n",
    "\n",
    "代码中用 `np.linalg.inv(A)` 计算了基底矩阵 $A$ 的逆矩阵，然后通过 `A_inv @ a` 执行矩阵乘法，得到了向量 $\\boldsymbol{a}$ 在新基底下的坐标表达。\n",
    "\n",
    "---\n",
    "\n",
    "### 4. 示例：当前选用的基底\n",
    "\n",
    "在这段代码中选用的基底 $A$ 是一个规范正交基（实际上是标准正交基的每个向量取了反向）：\n",
    "\n",
    "$$\n",
    "A = \\begin{bmatrix}\n",
    "-1 & 0 \\\\\n",
    "0 & -1\n",
    "\\end{bmatrix}\n",
    "$$\n",
    "\n",
    "由于该矩阵是对标准基的简单反转，其逆矩阵为其自身（即 $A^{-1} = A$），因此：\n",
    "\n",
    "$$\n",
    "\\boldsymbol{a}' = A^{-1} \\boldsymbol{a} = A \\cdot \\boldsymbol{a} = \\begin{bmatrix} -1 & 0 \\\\ 0 & -1 \\end{bmatrix} \\begin{bmatrix} 3 \\\\ 4 \\end{bmatrix} = \\begin{bmatrix} -3 \\\\ -4 \\end{bmatrix}\n",
    "$$\n",
    "\n",
    "这表示：**在该新基底下，向量 $\\boldsymbol{a}$ 的表示是 $\\begin{bmatrix} -3 \\\\ -4 \\end{bmatrix}$**。\n",
    "\n",
    "---\n",
    "\n",
    "### 总结\n",
    "\n",
    "这段代码完成了一个标准的**基底变换**过程，目标是将一个向量 $\\boldsymbol{a}$ 从标准坐标系转换为任意基底 $A$ 下的坐标表示。通用公式是：\n",
    "\n",
    "$$\n",
    "\\text{new coordinates} = A^{-1} \\cdot \\boldsymbol{a}\n",
    "$$\n",
    "\n",
    "它在数值线性代数、计算机图形学、数据科学的特征空间变换中具有广泛的应用。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "079f9065-387a-4c9e-86e2-e67254af4d61",
   "metadata": {},
   "source": [
    "## 初始化"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "46e60434-c1e1-46f8-ba27-ed29b43c2d8c",
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5c8b1106-ba35-4c2e-89a1-02f3eb97dabc",
   "metadata": {},
   "source": [
    "## 定义向量"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "deffe1e9-18f8-4d74-83c9-8da957051baa",
   "metadata": {},
   "outputs": [],
   "source": [
    "a = np.array([[3],\n",
    "              [4]])"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3444ff8d-dbc4-460e-8505-288cf7fe4263",
   "metadata": {},
   "source": [
    "## 定义不同基底"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "id": "c01380d1-fa69-42e2-a576-839cc39160a5",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 规范正交基\n",
    "A = np.array([[-1, 0],\n",
    "              [0, -1]])\n",
    "\n",
    "# 规范正交基\n",
    "# A = np.array([[3/5, -4/5],\n",
    "#               [4/5, 3/5]])\n",
    "\n",
    "# 正交基\n",
    "# A = np.array([[-4/5, -3/2],\n",
    "#               [3/5, -2]])\n",
    "\n",
    "# 非正交基\n",
    "# A = np.array([[2, 1],\n",
    "#               [1, 3]])"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "bd21dea4-f06f-4f2d-9a38-7f50df6cfdcc",
   "metadata": {},
   "source": [
    "## 计算逆矩阵"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "id": "dca24e5a-a800-4924-b48f-80f2f86431c1",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[-1., -0.],\n",
       "       [-0., -1.]])"
      ]
     },
     "execution_count": 37,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "A_inv = np.linalg.inv(A)\n",
    "A_inv"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a44a7315-7066-479a-a475-a46b16c20e2c",
   "metadata": {},
   "source": [
    "## 计算坐标"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "id": "b7de6a28-e2ab-484e-a6ff-452ce58bce5a",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[-3.],\n",
       "       [-4.]])"
      ]
     },
     "execution_count": 39,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "A_inv @ a"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c9f7081d-73bb-4a49-a811-05b06b081ef4",
   "metadata": {},
   "source": [
    "作者\t**生姜DrGinger**  \n",
    "脚本\t**生姜DrGinger**  \n",
    "视频\t**崔崔CuiCui**  \n",
    "开源资源\t[**GitHub**](https://github.com/Visualize-ML)  \n",
    "平台\t[**油管**](https://www.youtube.com/@DrGinger_Jiang)\t\t\n",
    "\t\t[**iris小课堂**](https://space.bilibili.com/3546865719052873)\t\t\n",
    "\t\t[**生姜DrGinger**](https://space.bilibili.com/513194466)  "
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python [conda env:base] *",
   "language": "python",
   "name": "conda-base-py"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.12.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
